package org.oreilly.javaGoodParts.examples.impl;

import java.util.HashMap;
import java.util.List;
import java.util.UUID;

import org.oreilly.javaGoodParts.examples.statistics.Player;
import org.oreilly.javaGoodParts.examples.statistics.Team;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;

/**
 * A fourth implementation of the Team interface, using a HashSet as the backing
 * store for the Players on the team, after the interface has been changed to
 * return a Set from the getPlayers() method. This iteration adds methods that
 * allow getting player records in a random access fashion. One method allows
 * getting a {@link List} of {@link Player} objects for a player from the name,
 * and the other allows getting a {@link Player} object from the player id. To
 * do this, we add two {@link HashMap} objects to the private fields.
 */
public class TeamImpl implements Team {

	private final String name;
	private final HashMultimap<String, Player> byName = HashMultimap.create();
	private final HashMap<UUID, Player> byIds = Maps.newHashMap();

	/**
	 * Create a TeamImpl object, with the name supplied
	 */
	public TeamImpl(String teamName) {
		name = teamName;
	}

	/**
	 * Return a <code>String</code> that is the name of this team
	 */
	public String getName() {
		return name;
	}

	/**
	 * Return a set of the players that are on this team
	 */
	public ImmutableSet<Player> getRoster() {
		return ImmutableSet.copyOf(byIds.values());
	}

	/**
	 * Add a player to the team
	 */
	public void addPlayer(Player toAdd) {
		byName.put(toAdd.getName(), toAdd);
		byIds.put(toAdd.getId(), toAdd);
	}

	/**
	 * Remove a player from the team
	 */
	public void removePlayer(Player toRemove) {
		byName.remove(toRemove.getName(), toRemove);
		byIds.remove(toRemove.getId());
	}

	@Override
	public ImmutableSet<Player> findPlayers(String name) {
		return ImmutableSet.copyOf(byName.get(name));
	}

	@Override
	public Player getPlayer(UUID playerId) {
		return byIds.get(playerId);
	}
}
